using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class XRootContext : XMonoSingleton<XRootContext>
{
    private string currentScenePath;

    /// <summary>
    /// current load type list
    /// </summary>
    private List<System.Type> typeList = new List<System.Type>();

    /// <summary>
    /// startup
    /// </summary>
    /// <param name="types"></param>
    /// <returns></returns>
    public bool Startup(System.Type[] types)
    {
        foreach(System.Type type in types)
        {
            XPlugin plugin = XPluginManager.GetSingleton().LoadPlugin(type);
            if (plugin)
            {
#if UNITY_EDITOR || UNITY_DEVELOP
                GLog.Log("[Root] load plugin <color=red>{0}</color> succeed", type.ToString());
#endif
                typeList.Add(type);
            }
        }
        
        return true;
    }

    /// <summary>
    /// shutdown, cleaup all resources
    /// </summary>
    public void Shutdown()
    {
        foreach(System.Type type in typeList)
            XPluginManager.GetSingleton().UnloadPlugin(type);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T QueryPlugin<T>() where T : XPlugin
    {
        return XPluginManager.GetSingleton().QueryPlugin<T>();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="path"></param>
    /// <param name="complete"></param>
    /// <returns></returns>
    public Coroutine LoadSceneAsync(string path, System.Action<string> complete)
    {
        return StartCoroutine(OnLoadSceneAsync(path, complete));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="path"></param>
    /// <param name="complete"></param>
    /// <returns></returns>
    private IEnumerator OnLoadSceneAsync(string path, System.Action<string> complete)
    {
        yield return Resources.UnloadUnusedAssets();

        // force gc
        System.GC.Collect();

        if (currentScenePath != path)
        {
            currentScenePath = path;
            
            yield return XRes.LoadSceneAsync(path, (success) => {
                complete?.Invoke(path);
            });
        }
        else
        {
            complete?.Invoke(path);
        }
    }
}
